package appSocket

import (
	"bytes"
	"encoding/binary"
	"net"
	"time"
	"encoding/json"

	"gitee.com/DengAnbang/goutils/loge"
)

const (
	HeaderLength = 4 //头的长度
	bytesSize    = 1024 * 4
)

type packet struct {
	headerLength     int       //头的长度
	LastTimeAccessed time.Time //心跳时间
	packetID         string    //id
	conn             net.Conn
	data             []byte
}

func NewConnUtil(conn net.Conn) *packet {
	return &packet{
		headerLength:     HeaderLength,
		conn:             conn,
		LastTimeAccessed: time.Now(),
	}
}

//封包
func (packet *packet) Ping() {
	packet.SendMsg(TypePing, "ping:"+packet.packetID)
}
func (packet *packet) Packet(message []byte) *packet {
	messageLen := len(message)
	i := make([]byte, 0, packet.headerLength+messageLen)
	i2 := append(i, IntToBytes(messageLen)...)
	packet.data = append(i2, message...)
	return packet
}
func (packet *packet) Close() {
	packet.conn.Close()
}

//发送消息
func (packet *packet) sendMsgByte(message []byte) {
	packet.Packet(message)
	packet.conn.Write(packet.data)
}

func (packet *packet) SendMsg(messageType int, data interface{}) {
	message := NewSocketMessage(messageType, data)
	socketMessage, err := json.Marshal(message)
	if err == nil {
		packet.sendMsgByte(socketMessage)
	} else {
		loge.Wf("json编码错误:$s---err:%s", message.String(), err.Error())
	}
}
func (packet *packet) SendMsgErr(messageType int, debugMsg string) {
	message := NewSocketMessage(messageType, nil)
	message.DebugMsg = debugMsg
	socketMessage, err := json.Marshal(message)
	if err == nil {
		packet.sendMsgByte(socketMessage)
	} else {
		loge.Wf("json编码错误:$s---err:%s", message.String(), err.Error())
	}
}

//解包
func (packet *packet) Unpack() []byte {
	return packet.data[HeaderLength:]
}

//读取包
func (packet *packet) ReadConn(readerChannel chan<- []byte) error {
	readBytes := make([]byte, bytesSize)
	conn := packet.conn
	defer conn.Close()
	defer close(readerChannel)
	buffer := bytes.NewBuffer(make([]byte, 0, bytesSize))
	for {
		n, err := conn.Read(readBytes)
		if err != nil {
			return err
		}
		buffer.Write(readBytes[:n])
		//是否包含了头
		if buffer.Len() >= packet.headerLength {
			dataLen := BytesToInt(buffer.Bytes()[:packet.headerLength])
			//包含应该完整的包了
			if buffer.Len() >= packet.headerLength+dataLen {
				packet.data = buffer.Bytes()[:packet.headerLength+dataLen]
				unpack := packet.Unpack()
				readerChannel <- unpack[:dataLen]
				last := buffer.Bytes()[packet.headerLength+dataLen:]
				buffer = bytes.NewBuffer(make([]byte, 0, bytesSize))
				buffer.Write(last)
			}
		}
	}

}

//整形转换成字节
func IntToBytes(n int) []byte {
	x := int32(n)
	bytesBuffer := bytes.NewBuffer([]byte{})
	binary.Write(bytesBuffer, binary.BigEndian, x)
	return bytesBuffer.Bytes()
}

//字节转换成整形
func BytesToInt(b []byte) int {
	bytesBuffer := bytes.NewBuffer(b)
	var x int32
	binary.Read(bytesBuffer, binary.BigEndian, &x)
	return int(x)
}
